<script setup lang="ts">
import { EOrderPayWay } from '@/enum';
import useModal from '@/hooks/useModal';
import useToast from '@/hooks/useToast';
import HomeRequest from '@/request/homeRequest';
import OrderRequest from '@/request/orderRequest';
import UserRequest from '@/request/userRequest';
import { useAppStore } from '@/store';
import OrderAdditionalInfo from '@/subcontract/home/submitOrder/component/OrderAdditionalInfo.vue';
import OrderPlayMode from '@/subcontract/home/submitOrder/component/OrderPlayMode.vue';
import OrderProduct from '@/subcontract/home/submitOrder/component/orderProduct/index.vue';
import OrderSubmitRemark from '@/subcontract/home/submitOrder/component/OrderSubmitRemark.vue';
import ReceivingAddress from '@/subcontract/home/submitOrder/component/receivingAddress/index.vue';
import { isArray } from '@/utils/is';
import { navigate } from '@/utils/navigate';
import { requestPayment } from '@/utils/requestPayment';
import to from '@/utils/to';
import Tools from '@/utils/tools';
import validate, { IValidator } from '@/utils/validate';

interface IState {
  params: {
    beeperId: number;
    businessIds?: string;
    goodsIds?: string;
    serverIds?: string;
    thirdClassifyIds?: string;
    ruleIds?: string;
    variantIds: string;
  };
  productList: IProductInformation[];
  callerDevicePartInfo?: IObtainCallerDevicePartInfoRes;
  address?: IListShippingAddressesRes;
  isEditAddress: boolean;
  off: boolean; // 存在即是不符合条件的地址
  amount: {
    packagingFee: number; // 包装费
    deliveryFee: number; // 配送费
    payTotalFee: number; // 总价
    payableTotalFee: number; // 未抵扣养老金/物业金 总价
    depositFee: number; // 抵押金
    promoteGainFee: number; //推广优惠金额
  };
  calculateOrderPriceInfo?: ICalculateOrderPriceRes;
  resultAttrData: IGoodsAdditionalInfo[][];
  paymentOnBehalfShow: boolean;
  paymentOnBehalfUrl: string;
  orderParams: {
    [key: string]: any;
  };
}

const store = useAppStore();
const { showToast } = useToast();
const { showModal } = useModal();
const state = reactive<IState>({
  params: { beeperId: store.$state.beeperId, variantIds: '' },
  productList: [],
  isEditAddress: false,
  off: true,
  amount: { packagingFee: 0, deliveryFee: 0, payTotalFee: 0, payableTotalFee: 0, depositFee: 0, promoteGainFee: 0 },
  resultAttrData: [],
  paymentOnBehalfShow: false,
  paymentOnBehalfUrl: '',
  orderParams: {
    openId: store.$state.userInfo.openId,
    beeperId: store.$state.beeperId,
    btnId: store.$state.btnInformation!.id,
    btnServerClassifyIds: store.$state.btnInformation!.classifyIds,
    queryType: store.$state.beeperParams.queryType,
    payType: 1,
    amount: 0,
    orderRemark: '',
    voiceRemark: '',
    harvestAddressId: 0,
    waiterExpectedDate: '',
    oldAmountoff: true,
    pmcAmountoff: true,
  },
});
const addressValidators: IValidator<any>[] = [
  { key: 'houseNumber', name: '住址', required: true, requiredMsg: '住址为必填项，且必须选到门牌号' },
  { key: 'phone', name: '联系人电话', required: true, rule: /^(?:\+86)?1[3-9]\d{9}$/ },
  { key: 'linkName', name: '联系人', required: true },
];

onLoad((options) => {
  if (!options) return;
  if (options.products) {
    state.productList = isArray(JSON.parse(decodeURIComponent(options.products))) ? JSON.parse(decodeURIComponent(options.products)) : [JSON.parse(decodeURIComponent(options.products))];
  } else if (store.$state.shoppingCart.length > 0) {
    state.productList = store.$state.shoppingCart;
  } else {
    showToast('没有产品信息，请联系客服处理').then(() => {
      setTimeout(() => {
        navigate({ url: '', type: 'navigateBack' });
      }, 500);
    });
    return;
  }
  state.params = { ...state.params, businessIds: state.productList.map((item) => item.businessId).toString(), variantIds: state.productList.map((item) => item.variantId).toString() };
  fetchObtainCallerDevicePartInfo();
});

watch(
  () => state.address,
  (address) => {
    if (!address) return;
    fetchCalculateOrderPrice();
  },
);

// 获得呼叫器部分信息
const fetchObtainCallerDevicePartInfo = () => {
  const { beeperId, businessIds } = state.params;
  HomeRequest.ObtainCallerDevicePartInfo({ beeperId, businessIds, hasLoading: true }).then((res) => {
    state.callerDevicePartInfo = res.data;
  });
};

// 计算订单价格
const fetchCalculateOrderPrice = () => {
  const params = {
    list: state.productList.map((item) => ({
      beeperBtnId: item.id,
      nums: item.nums,
      variantId: item.variantId,
      goodsType: item.goodsType,
      variantIds: item.variantIds && item.variantIds.length > 0 ? item.variantIds.split(',') : '',
      name: item.name,
    })),
    beeperId: store.$state.beeperId,
    addressId: state.address!.harvestAddressId,
    hasLoading: true,
  };
  OrderRequest.CalculateOrderPrice(params)
    .then((res) => {
      state.calculateOrderPriceInfo = res.data;
      state.amount = {
        packagingFee: res.data.list.reduce((a, b) => a + b.packageAmount, 0),
        deliveryFee: res.data.list.reduce((a, b) => a + b.deliveryAmount, 0),
        payTotalFee: res.data.payTotalAmount,
        payableTotalFee: res.data.payableTotalAmount,
        depositFee: res.data.list.reduce((a, b) => a + b.depositAmount, 0),
        promoteGainFee: res.data.list.reduce((a, b) => a + b.promoteGain, 0),
      };
      state.orderParams = { ...state.orderParams, params: res.data.list };
      state.orderParams.oldAmountoff = !!res.data.discountOld;
      state.orderParams.pmcAmountoff = !!res.data.discountPmc;
    })
    .catch(() => {
      setTimeout(() => {
        navigate({ url: '', type: 'navigateBack' });
      }, 800);
    });
};

// 物业金养老金改变事件
const handleDeductionFeeChange = (deductionFee: { discountOld: boolean; discountPmc: boolean }) => {
  if (deductionFee.discountOld) {
    state.amount.payTotalFee = state.amount.payableTotalFee - state.calculateOrderPriceInfo!.discountOld;
    state.orderParams.oldAmountoff = true;
  } else {
    state.amount.payTotalFee = state.amount.payTotalFee + state.calculateOrderPriceInfo!.discountOld;
    state.orderParams.oldAmountoff = false;
  }
  if (deductionFee.discountPmc) {
    state.amount.payTotalFee = state.amount.payableTotalFee - state.calculateOrderPriceInfo!.discountPmc;
    state.orderParams.pmcAmountoff = true;
  } else {
    state.amount.payTotalFee = state.amount.payTotalFee + state.calculateOrderPriceInfo!.discountPmc;
    state.orderParams.pmcAmountoff = false;
  }
};

// 预计送达时间change事件
const handleExpectedTimeChange = (payload: { date: string; orderId: number; key: string }) => {
  state.orderParams.params = state.orderParams.params.map((item: { [key: string]: any }) => {
    return item.key === payload.key ? { ...item, earliestTime: payload.date, expectedTimeStr: payload.date } : item;
  });
};

// 服务时间change
const handleServerTimeChange = (payload: { date: string; orderId: number; key: string }) => {
  state.orderParams.waiterExpectedDate = payload.date;
};

// 地址改变
const handleReceivingAddressChange = (isEditAddress: boolean, address?: IListShippingAddressesRes, off?: number) => {
  state.isEditAddress = isEditAddress;
  state.off = !!off;
  state.address = address;
};

// 关闭他人代付二维码弹窗
const handleClosePaymentOnBehalf = () => {
  state.paymentOnBehalfShow = false;
  navigate({ type: 'switchTab', url: '/pages/order/index' });
};

// 提交订单
const handleSubmitOrder = async () => {
  if (!state.address) {
    await showToast('请先选择收货地址');
    return;
  }
  const isAddressValid = validate(state.address!, addressValidators);
  if (!isAddressValid) return;
  if (state.productList.find((item) => item.goodsType === 4) && !state.orderParams.waiterExpectedDate) {
    await showToast('请选择服务时间');
    return;
  }
  const additionalInfo = state.resultAttrData.flat();
  const additionalInfoRequired = additionalInfo.find((item) => item.requiredFlag && !item.value);
  if (additionalInfoRequired) {
    await showToast(`${additionalInfoRequired.attrName}不能为空`);
    return;
  }
  state.orderParams.harvestAddressId = state.address.harvestAddressId;
  state.orderParams.amount = state.amount.payTotalFee;
  state.orderParams.orderAttrs = await Promise.all(
    additionalInfo.map(async (item) => {
      if (item.fieldType === 8 && item.value) {
        return { ...item, value: await Tools.uniBase64FromFile(item.value) };
      }
      return item;
    }),
  );
  if (state.orderParams.voiceRemark) {
    state.orderParams.voiceRemark = await Tools.uniBase64FromFile(state.orderParams.voiceRemark);
  }
  // 是否是0元购产品
  if (state.orderParams.amount === 0) state.orderParams.payType = 5;
  // 是否是挂号对接产品
  if (store.$state.btnInformation?.eventId === 18) {
    state.orderParams.strDate = Tools.formatTimestamp(store.$state.registerData.timeStamp, 'YYYY-MM-DD');
  }
  const resultModal = await showModal(`确定使用${EOrderPayWay[state.orderParams.payType]}？`, { showCancel: true });
  if (resultModal.cancel) return;
  // 如果不存在新增地址，且地址不符合条件，需要新增地址再提交订单
  if (!state.isEditAddress && state.off) {
    const [err, res] = await to(UserRequest.SaveShippingAddress({ ...state.address, harvestAddressId: '', relationBeeperId: state.address.beeperId, relationBeeperType: state.callerDevicePartInfo?.addressType }));
    if (err) return;
    state.orderParams.harvestAddressId = res.data;
  }
  const [err, res] = await to(OrderRequest.CreateOrderSubmit({ ...state.orderParams, hasLoading: true }));
  if (err) return;
  if (res.data) {
    // 他人代付逻辑
    if (state.orderParams.payType === 4) {
      const [QRcodeErr, QRcodeRes] = await to(HomeRequest.WeChatMiniProQRCode({ value: res.data, key: 'originNo', url: 'subcontract/home/paymentByOthers/index' }));
      if (QRcodeErr) return;
      const base64File = await Tools.base64ToImage(QRcodeRes.data, 'paymentByOthersQRCode');
      if (!base64File) return;
      state.paymentOnBehalfUrl = base64File;
      state.paymentOnBehalfShow = true;
      return;
    }
    const [payErr] = await to(requestPayment({ ...res.data, provider: 'wxpay', orderInfo: '' }));
    if (payErr) return;
    navigate({ type: 'switchTab', url: '/pages/order/index' });
  } else {
    navigate({ type: 'switchTab', url: '/pages/order/index' });
  }
};
</script>

<template>
  <view class="c-pd" :style="{ paddingBottom: store.$state.systemInfo.safeAreaInsets!.bottom + 50 + 12 + 'px' }">
    <!-- 收货地址 -->
    <ReceivingAddress v-if="state.callerDevicePartInfo" :params="state.params" :callerDevicePartInfo="state.callerDevicePartInfo" :productList="state.productList" @change="(payLoad) => handleReceivingAddressChange(payLoad.isEditAddress, payLoad.address, payLoad.off)" />
    <!-- 产品与费用显示 -->
    <OrderProduct
      v-if="state.callerDevicePartInfo && state.calculateOrderPriceInfo"
      :products="state.productList"
      :callerDevicePartInfo="state.callerDevicePartInfo"
      :calculateOrderPriceInfo="state.calculateOrderPriceInfo"
      :amount="state.amount"
      @discountChange="handleDeductionFeeChange"
      @expectedTimeChange="handleExpectedTimeChange"
      @serverTimeChange="handleServerTimeChange"
    />
    <!-- 支付方式 -->
    <OrderPlayMode
      v-if="state.callerDevicePartInfo && state.calculateOrderPriceInfo"
      :products="state.productList"
      :callerDevicePartInfo="state.callerDevicePartInfo"
      :calculateOrderPriceInfo="state.calculateOrderPriceInfo"
      @change="(payType) => (state.orderParams.payType = payType)"
    />
    <!-- 备注 -->
    <OrderSubmitRemark
      @change="
        (payload) => {
          state.orderParams.voiceRemark = payload.voiceRemark;
          state.orderParams.orderRemark = payload.orderRemark;
        }
      "
    />
    <!-- 附加信息 -->
    <OrderAdditionalInfo :products="state.productList" @change="(resultAttrData) => (state.resultAttrData = resultAttrData)" />
  </view>

  <view class="h-50px bg-white w-screen pos-fixed left-0 bottom-0 z-99" :style="{ paddingBottom: store.$state.systemInfo.safeAreaInsets!.bottom + 'px' }">
    <van-divider hairline custom-style="margin: 0" />
    <view class="h-full w-full py-4px px-12px box-border flex justify-between items-center" v-if="state.address">
      <view class="flex flex-1 h-full">
        <view class="flex-col flex justify-center">
          <view class="text-red">
            ¥<text class="text-20px fw-bold ml-4px">{{ state.amount.payTotalFee }}</text>
          </view>
        </view>
      </view>
      <view class="h-90% c-br c-bg flex items-center justify-center text-white px-30px c-text-16" @click="handleSubmitOrder">提交订单</view>
    </view>
    <view class="h-full w-full py-4px flex justify-center items-center fw-bold text-red" v-else> 请先选择地址 </view>
  </view>

  <van-popup :show="state.paymentOnBehalfShow">
    <view class="c-br c-pd w-screen">
      <view class="c-br bg-white c-pd">
        <image class="w-full h-300px" :src="state.paymentOnBehalfUrl" lazy-load mode="aspectFill" />
      </view>
    </view>
    <view class="w-full flex justify-center">
      <i class="i-ci:close-circle text-white text-[32px]" @click="handleClosePaymentOnBehalf"></i>
    </view>
  </van-popup>
</template>

<style lang="scss" scoped>
@import './index.scss';
</style>
